package com.dingreading.cloud.admin.service.impl;

import com.dingreading.cloud.admin.dto.StoreManagementFeeDto;
import com.dingreading.cloud.admin.entity.StoreManagementFee;
import com.dingreading.cloud.admin.entity.table.StoreManagementFeeTableDef;
import com.dingreading.cloud.admin.mapper.StoreManagementFeeMapper;
import com.dingreading.cloud.admin.service.StoreManagementFeeService;
import com.dingreading.cloud.admin.util.AdminStaffRoleUtil;
import com.dingreading.cloud.common.util.DateUtil;
import com.dingreading.cloud.common.util.NepUtil;
import com.dingreading.cloud.common.util.PageUtil;
import com.dingreading.cloud.common.util.QueryFiledUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryOrderBy;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

import static com.dingreading.cloud.admin.entity.table.StoresTableDef.stores;

/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2024-11-18
 */
@Service
public class StoreManagementFeeServiceImpl extends BaseServiceImpl<StoreManagementFeeMapper, StoreManagementFee, StoreManagementFeeTableDef> implements StoreManagementFeeService {

    @Override
    protected StoreManagementFeeTableDef getTable() {
        return StoreManagementFeeTableDef.storeManagementFee;
    }

    @Override
    public Page<StoreManagementFeeDto> pageList(
            PageUtil pageUtil, String storeUid, String staffUid, Integer status, String beginDate, String endDate,
            Integer orderStatus, List<String> identifyList
    ) {
        QueryCondition condition = QueryCondition.createEmpty();
        if (status != null) {
            condition.and(table.status.eq(status));
        } else {
            Date nowDatetime = DateUtil.getNowDatetime();
            Date date = DateUtil.addMonths(nowDatetime, -3);
            QueryCondition statusCondition = table.status.in(1, 0)
                    .or(table.status.eq(-1).and(table.closeTime.gt(date)));
            condition.and(statusCondition);
        }
        if (StringUtils.isNotBlank(storeUid))
            condition.and(table.storeUid.eq(storeUid));
        if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate))
            condition.and(table.expiryTime.between(QueryFiledUtil.appendMin00(beginDate), QueryFiledUtil.appendMin24(endDate)));

        boolean superAdmin = AdminStaffRoleUtil.isSuperAdmin(identifyList);
        boolean manager = AdminStaffRoleUtil.isManager(identifyList);
        boolean supervise = AdminStaffRoleUtil.isSupervise(identifyList);
        if (!superAdmin && !manager && !supervise) {
            QueryWrapper storeWrapper = QueryWrapper.create()
                    .select(stores.uid)
                    .from(stores)
                    .where(stores.operateStaffUid.isNotNull().and(stores.operateStaffUid.eq(staffUid)));
            condition.and(table.storeUid.in(storeWrapper));
        }

        QueryOrderBy[] order = null;
        if (orderStatus != null) {
            if (orderStatus.equals(1))
                order = new QueryOrderBy[]{table.expiryTime.asc()};
            else
                order = new QueryOrderBy[]{table.expiryTime.desc()};
        } else {
            order = new QueryOrderBy[]{table.expiryTime.desc()};
        }

        QueryWrapper wrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(order);

        return getMapper().paginateWithRelationsAs(Page.of(pageUtil.getPage(), pageUtil.getRows()), wrapper, StoreManagementFeeDto.class);
    }

    @Override
    public List<StoreManagementFee> listByStoreUid(String storeUid) {
        QueryWrapper wrapper = QueryWrapper.create().where(table.storeUid.eq(storeUid));
        return getMapper().selectListWithRelationsByQuery(wrapper);
    }

    @Override
    public boolean updateStatus(Long id, Double payAmount, Date payTime, String remark, String operatorUid, String operatorName) {
        return UpdateChain.of(StoreManagementFee.class)
                .set(table.payTime, payTime)
                .set(table.payAmount, payAmount)
                .set(table.status, 1)
                .set(table.remark, remark)
                .set(table.operatorUid, operatorUid)
                .set(table.operatorName, operatorName)
                .where(table.id.eq(id))
                .update();
    }

    @Override
    public boolean close(Long id, String closeRemark, String headStaffUid, String headStaffName) {
        return UpdateChain.of(StoreManagementFee.class)
                .set(table.status, -1)
                .set(table.closeRemark, closeRemark)
                .set(table.closeTime, DateUtil.getNowDatetime())
                .set(table.lastStaffUid, NepUtil.nullToZero(headStaffUid))
                .set(table.lastStaffName, NepUtil.nullToZero(headStaffName))
                .where(table.id.eq(id))
                .update();
    }

    @Override
    public boolean recover(Long id, String headStaffUid, String headStaffName) {
        return UpdateChain.of(StoreManagementFee.class)
                .set(table.payTime, null)
                .set(table.payAmount, null)
                .set(table.url, null)
                .set(table.status, 0)
                .set(table.remark, null)
                .set(table.lastStaffUid, NepUtil.nullToZero(headStaffUid))
                .set(table.lastStaffName, NepUtil.nullToZero(headStaffName))
                .where(table.id.eq(id))
                .update();
    }

    @Override
    public StoreManagementFee getByIdRalation(Long id) {
        return getMapper().selectOneWithRelationsByCondition(table.id.eq(id));
    }

    @Override
    public List<StoreManagementFee> listByExport(
            String storeUid, String staffUid, Integer status, String beginDate, String endDate, Integer orderStatus,
            List<String> identifyList
    ) {
        QueryCondition condition = QueryCondition.createEmpty();
        if (status != null) {
            condition.and(table.status.eq(status));
        } else {
            Date nowDatetime = DateUtil.getNowDatetime();
            Date date = DateUtil.addMonths(nowDatetime, -3);
            QueryCondition statusCondition = table.status.in(1, 0)
                    .or(table.status.eq(-1).and(table.closeTime.gt(date)));
            condition.and(statusCondition);
        }
        if (StringUtils.isNotBlank(storeUid))
            condition.and(table.storeUid.eq(storeUid));
        if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate))
            condition.and(table.expiryTime.between(QueryFiledUtil.appendMin00(beginDate), QueryFiledUtil.appendMin24(endDate)));

        boolean superAdmin = AdminStaffRoleUtil.isSuperAdmin(identifyList);
        boolean manager = AdminStaffRoleUtil.isManager(identifyList);
        if (!superAdmin && !manager) {
            QueryWrapper storeWrapper = QueryWrapper.create()
                    .select(stores.uid)
                    .from(stores)
                    .where(stores.operateStaffUid.isNotNull().and(stores.operateStaffUid.eq(staffUid)));
            condition.and(table.storeUid.in(storeWrapper));
        }

        QueryOrderBy[] order = null;
        if (orderStatus != null) {
            if (orderStatus.equals(1))
                order = new QueryOrderBy[]{table.expiryTime.asc()};
            else
                order = new QueryOrderBy[]{table.expiryTime.desc()};
        } else {
            order = new QueryOrderBy[]{table.expiryTime.desc()};
        }

        QueryWrapper wrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(order);
        return getMapper().selectListWithRelationsByQuery(wrapper);
    }

}
